<template>
  <div class="app-container" v-loading="pageLoading">
    <el-row :gutter="20">
      <el-col :span="ListSpan">
        <div class="driver-view">
          <div class="driver-container">
            <div class="driver" :isChecked="chooseDriverName == driver.Name" v-for="(driver, index) in driversList"
              :key="index">
              <div class="flex f-i-c ">
                <div class="driver-logo mr-10" :connect="driver.AtStation" :isbadcode="driver.isbadcode">
                  {{ driver.Name }}
                </div>
                <div class="driver-msg">
                  <div class="mb-10">
                    <span class="mr-4">状态:</span>
                    <!-- <el-tag :type="['primary','error','warning'][0]">正常</el-tag> -->
                    <!-- {{driver.State}} -->
                    <el-tag :type="asyncOptionName('stuatsOptions', driver.State, true)">{{
                      asyncOptionName('stuatsOptions', driver.State) }}</el-tag>
                  </div>
                  <div>
                    <span class="mr-4">事件:</span>
                    <span class="text-gray">{{ driver.Event }}</span>

                  </div>
                </div>
              </div>
              <div class="driver-content" v-if="!LogShow">
                <div class="flex f-c-sb f-i-c mb-10">
                  <div>
                    <span class="mr-4">列:</span>
                    <el-tag type="info">{{ driver.UserColumn }}</el-tag>
                  </div>
                  <div>
                    <span class="mr-4">层:</span>
                    <el-tag type="info">{{ driver.UserLevel }}</el-tag>
                  </div>
                  <div>
                    <span class="mr-4">任务号:</span>
                    <el-tag type="info">{{ driver.TaskId }}</el-tag>
                  </div>
                </div>
                <div>
                  <span class="mr-4">故障码:</span>
                  <el-tag type="success" v-if="driver.ErrorCode == 0">正常</el-tag>
                  <el-tag type="danger" v-else>{{ driver.ErrorCode }}</el-tag>
                </div>
              </div>
              <div class="driver-op" v-if="!LogShow">
                <el-button plain size="middle" type="primary"
                  @click.native="chooseDriver(driver, 1, index)">手控</el-button>
                <el-button plain size="middle" type="primary"
                  @click.native="chooseDriver(driver, 2, index)">故障</el-button>
                <el-button v-if="driver.LockerUser" plain @click="lockMethod('CraneUnLocker', driver.Name)"
                  size="middle" type="warning">解锁</el-button>
                <el-button v-else plain @click="lockMethod('CraneLocker', driver.Name)" size="middle"
                  type="warning">锁定</el-button>
              </div>
            </div>
          </div>
        </div>
      </el-col>
      <el-col v-if="LogShow" :span="18">

        <div class="setoption">
          <div class="setoption-sesion">
            <el-button size="middle" :disabled="opsLoading" @click="backHome" type="primary">返回</el-button>
            <el-button size="middle" :disabled="opsLoading" type="warning" @click="opsMethod('CraneUnLocker')"
              v-if="chooseDriverListForIndex.LockerUser">解锁</el-button>
            <el-button v-else size="middle" :disabled="opsLoading" type="warning"
              @click="opsMethod('CraneLocker')">锁定</el-button>

            <el-button size="middle" :disabled="opsLoading" type="warning"
              @click="opsMethod('CancelEmergencyStop')">复位</el-button>
            <el-button size="middle" :disabled="opsLoading" type="danger"
              @click="opsMethod('EmergencyStop')">急停</el-button>
            <el-button size="middle" :disabled="opsLoading" type="info"
              @click="opsMethod('BackToTheOrigin')">原点</el-button>
          </div>
          <div class="setoption-sesion" style="">
            <label-item class="mb-10" :dataCloumns="dataCloumns" :data="chooseDriverListForIndex"
              :labelProps="{ column: 3, border: true, colon: true, direction: 1, labelStyle: { width: '200px' }, }">
            </label-item>
            <div class="flex f-c-sa" style="width:60%">
              <div style="width:50%;border:1px solid #999" class="p-10">
                <h2>命令操作</h2>
                <label-item :dataCloumns="commonCloumns" :data="opsForm"
                  :labelProps="{ column: 1, border: false, colon: true, direction: 1, labelStyle: { width: '120px', lineHeight: '32px', textAlign: 'center' }, }">
                  <template #C_forkDirection>
                    <el-select v-model="opsForm.forkDirection">
                      <el-option v-for="(v, i) in forkDirectionOption" :key="i" :label="v.label"
                        :value="v.value"></el-option>
                    </el-select>
                  </template>
                  <template #C_userColumn>
                    <el-input-number v-model="opsForm.userColumn" :min="config.userColumnMin"
                      :max="config.userColumnMax" placeholder="列"></el-input-number>
                  </template>
                  <template #C_userLevel>
                    <el-input-number v-model="opsForm.userLevel" :min="config.userLevelMin" :max="config.userLevelMax"
                      placeholder="列"></el-input-number>
                  </template>
                </label-item>
                <div>
                  <el-button size="middle" type="success" :disabled="opsLoading" plain
                    @click="moveMethod('MoveByForkDirection')">运行</el-button>
                  <el-button size="middle" type="warning" :disabled="opsLoading" plain
                    @click="moveMethod('Pick')">取货</el-button>
                  <el-button size="middle" type="warning" :disabled="opsLoading" plain
                    @click="moveMethod('Putdown')">放货</el-button>
                </div>
              </div>
              <div style="width:50%;border:1px solid #999" class="p-10">
                <h2>单步操作</h2>
                <div class="flex-col f-c-c f-i-c">
                  <el-button :disabled="opsLoading" style="width:70px;height:70px" class="mb-10" type="info" plain
                    @click="opsMethod('Up')" title="提升">提升</el-button>
                  <div>
                    <el-button @click="opsMethod('Back')" title="后退" :disabled="opsLoading"
                      style="width:70px;height:70px" type="info" plain>后退</el-button>
                    <el-button @click="opsMethod('Down')" title="下降" :disabled="opsLoading"
                      style="width:70px;height:70px" type="info" plain>下降</el-button>
                    <el-button @click="opsMethod('ForWard')" title="前进" :disabled="opsLoading"
                      style="width:70px;height:70px" type="info" plain>前进</el-button>
                  </div>
                </div>
              </div>
            </div>

          </div>
          <div class="setoption-sesion">
            <label-item style="width:70%" :dataCloumns="dataErrorCloumns" :data="chooseDriverListForIndex"
              :labelProps="{ column: 1, border: true, colon: true, direction: 1, labelStyle: { width: '160px' }, }">
              <!-- <template #C_status="{key}">
              <el-tag :type="returnTypeOrLabelName(key,true)">{{returnTypeOrLabelName(key)}}</el-tag>
            </template>
            <template #C_priority="{key}">
              <el-tag :type="returnTypeOrLabelName(key,true)">{{returnTypeOrLabelName(key)}}</el-tag>
            </template>
            <template #C_taskSource="{key}">
              <div>{{returnTypeOrLabelName(key)}}</div>
            </template> -->
            </label-item>
          </div>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import commonMixin from '@/views/_common/mixin'
import LabelItem from '@/components/LabelItem'
export default {
  name: 'craneControl',
  mixins: [commonMixin],
  components: {
    LabelItem,
  },
  data() {
    return {
      consoleShow: false, //控制台展示
      consoleType: 1, //控制台模式展示
      devicesTimer: null, //设备链接Timer 控制
      cacheWebSocket: null, //缓存ws
      api: this.$api.wcsUrl + 'Wcs/WebSocket/GetCranes', //ws api 地址
      wsConnected: false, //ws 是否链接中
      TimerCallSec: 10, //多少秒回调一次数据
      chooseDriverName: null, //选择的设备Name
      chooseDriverIndex: null, //选择的设备Name
      chooseDriverData: {},
      forkDirectionOption: [], //堆垛机货叉方向选项
      driversList: [], //堆垛机数据
      dataCloumns: [
        {
          title: '设备名称',
          key: 'Name',
        },

        {
          title: '列',
          key: 'UserColumn',
        },
        {
          title: '层',
          key: 'UserLevel',
        },
        {
          title: '任务号',
          key: 'TaskId',
        },
        {
          title: '货叉水平位置状态',
          key: 'ForkHorizontalPosition',
          format: (item, data, key, value) => {
            return this.asyncOptionName('forkDirectionR', value)
          },
        },
        {
          title: '货叉垂直位置状态',
          key: 'ForkVerticalPosition',
          format: (item, data, key, value) => {
            return this.asyncOptionName('forkDirectionV', value)
          },
        },
      ],
      dataErrorCloumns: [
        {
          title: '任务号',
          key: 'TaskId',
        },
        {
          title: '故障名称',
          key: 'ErrorName',
        },
        {
          title: '故障描述',
          key: 'ErrorDescription',
        },
        {
          title: '故障处理',
          key: 'ErrorSolution',
        },
      ],

      commonCloumns: [
        { title: '货叉运动方向', key: 'forkDirection' },
        { title: '列', key: 'userColumn' },
        { title: '层', key: 'userLevel' },
      ],

      // 运动方向form表单
      opsForm: {
        forkDirection: '1',
        userColumn: 0,
        userLevel: 0,
      },
      config: {
        userColumnMin: 0,
        userColumnMax: 0,
        userLevelMin: 0,
        userLevelMax: 0,
      },
      opsLoading: false, //操作项中所有的disabled

      forkDirectionR: [
        { label: '未知', value: 0, type: 'primary' },
        { label: '中位', value: 1, type: 'primary' },
        { label: '左位', value: 2, type: 'primary' },
        { label: '左极限', value: 3, type: 'primary' },
        { label: '右位', value: 4, type: 'primary' },
        { label: '右极限', value: 5, type: 'primary' },
        { label: '左外', value: 6, type: 'primary' },
        { label: '左外极限', value: 7, type: 'primary' },
        { label: '左外', value: 8, type: 'primary' },
        { label: '右外极限', value: 9, type: 'primary' },
      ], //堆垛机货叉横向选项
      forkDirectionV: [
        { label: '未知', value: 0, type: 'primary' },
        { label: '中位', value: 1, type: 'primary' },
        { label: '低位', value: 2, type: 'primary' },
        { label: '高位', value: 3, type: 'primary' },
      ], //堆垛机货叉竖向选项
      stuatsOptions: [
        { label: '初始化', value: 0, type: 'info' },
        { label: '回原点', value: 1, type: 'info' },
        { label: '无货待命', value: 2, type: 'success' },
        { label: '有货待命', value: 3, type: 'success' },
        { label: '无货运行', value: 4, type: 'success' },
        { label: '有货运行', value: 5, type: 'success' },
        { label: '取货', value: 6, type: 'success' },
        { label: '放货', value: 7, type: 'success' },
        { label: '手动', value: 8, type: 'warning' },
        { label: '报警', value: 9, type: 'danger' },
        { label: '断开', value: 10, type: 'danger' },
      ], //堆垛机状态选项
      eventOptions: [
        { label: '初始化', value: 0, type: 'primary' },
        { label: '开始运行', value: 1, type: 'primary' },
        { label: '开始取货', value: 2, type: 'primary' },
        { label: '取货完成 ', value: 3, type: 'primary' },
        { label: '开始放货 ', value: 4, type: 'primary' },
        { label: '放货完成 ', value: 5, type: 'primary' },
        { label: '完成', value: 6, type: 'primary' },
        { label: '急停', value: 7, type: 'primary' },
        { label: '出错完成', value: 8, type: 'primary' },
        { label: '回原点', value: 9, type: 'primary' },
      ], //堆垛事件选项
    }
  },
  computed: {
    // 返回展示列表span nums
    ListSpan() {
      return this.consoleShow ? 6 : 24
    },
    // 是否展示控制台
    LogShow() {
      return this.consoleShow
    },
    // 返回选择数据下的回显
    chooseDriverListForIndex() {
      return this.driversList[this.chooseDriverIndex] || {}
    },
  },
  created() {
    this.wsConnect()
    this.getDictionaryOptions()
  },
  methods: {
    // 返回对应选项中对应的值
    asyncOptionName(optionsName, value, isType = false) {
      let tmp = this[optionsName].find((x) => x.value == value)
      return tmp ? tmp[['label', 'type'][Number(isType)]] || '' : ''
    },
    // list 中唯一解锁/锁定
    lockMethod(apiName, deviceName) {
      if (!deviceName) return
      this.opsLoading = true
      this.$request(this.$api.wcsUrl + 'wcs/CraneDevice/' + apiName, { deviceName })
        .then((r) => {
          this.$message.success('操作成功')
          this.sendMsg()
        })
        .finally(() => {
          this.opsLoading = false
        })
    },
    // 返回
    backHome() {
      this.chooseDriverData = null
      this.chooseDriverIndex = null
      this.chooseDriverName = null
      this.consoleShow = false
    },
    // 执行取货放货 || 执行移动操作
    moveMethod(apiName) {
      this.$request(this.$api.wcsUrl + 'wcs/CraneDevice/' + apiName, {
        deviceName: this.chooseDriverListForIndex.Name,
        ...this.opsForm,
      })
        .then((r) => {
          this.$message.success('操作成功')
          this.sendMsg()
        })
        .finally(() => {
          this.opsLoading = false
        })
    },

    // 批量整理操作设备名称下的数据
    opsMethod(apiName) {
      if (!apiName) return
      this.opsLoading = true
      this.$request(this.$api.wcsUrl + 'wcs/CraneDevice/' + apiName, { deviceName: this.chooseDriverListForIndex.Name })
        .then((r) => {
          this.$message.success('操作成功')
          this.sendMsg()
        })
        .finally(() => {
          this.opsLoading = false
        })
    },
    // 选择设备
    chooseDriver(driData, type, index) {
      if (this.chooseDriverName == driData.Name) return
      this.chooseDriverName = driData.Name
      this.chooseDriverData = driData
      this.chooseDriverIndex = index
      this.getSetOptionsMax(driData.Name)
      this.consoleType = type
      this.consoleShow = true
    },
    //获取字典数据
    getDictionaryOptions() {
      this.$request(this.$api.wcsUrl + 'platform/dictionary/getdirectchildren', {
        parentType: 'Crane_ForkDirection',
      }).then((r) => {
        this.forkDirectionOption = r.map((i) => ({
          label: i.label,
          value: i.value,
        }))
      })
    },
    // 依据Driver Name 获取当前设备最大设定值
    getSetOptionsMax(deviceName) {
      this.$request(this.$api.wcsUrl + 'wcs/CraneDevice/LoadCraneInfos', { deviceName }).then((r) => {
        this.config.userColumnMin = r.minColumn
        this.config.userColumnMax = r.maxColumn
        this.config.userLevelMin = r.minLevel
        this.config.userLevelMax = r.maxLevel
        this.opsForm.userColumn = r.minColumn
        this.opsForm.userLevel = r.minLevel
      })
    },
    // 连接事件
    wsConnect() {
      if (this.wsConnected && this.cacheWebSocket != null) return
      let url = `${this.api.replace('http', 'ws')}`
      let ws = new WebSocket(url)
      let that = this
      ws.onopen = function () {
        that.wsConnected = true
        that.$notify.success('已连接服务')
        that.sendMsg()
        that.devicesTimer = setInterval(() => {
          that.sendMsg()
        }, this.TimerCallSec * 1000)
      }
      ws.onmessage = function (e) {
        that.acceptMes(e.data)
      }
      ws.onclose = function (e) {
        that.wsConnected = false
        that.$notify.success('已关闭连接服务')
        //that.$message.warning('WCS设备监控已断开')
        if (that.devicesTimer) clearInterval(that.devicesTimer)
      }
      ws.onerror = function (e) {
        that.$notify.error('连接服务出错,请联系管理员')
      }
      this.cacheWebSocket = ws
    },
    // 关闭ws
    closeWs() {
      this.cacheWebSocket.close()
    },
    // 发送信息
    sendMsg(msg) {
      if (this.cacheWebSocket && this.wsConnected) {
        this.cacheWebSocket.send(msg)
      }
    },
    // 接受信息
    acceptMes(data) {
      let newArr = JSON.parse(data).map((x) => {
        let isbadcode = Number(Boolean(x.ErrorCode != 0))
        return {
          ...x,
          isbadcode,
        }
      })
      this.driversList = _.cloneDeep(newArr)
    },
  },
}
</script>

<style lang="scss" scoped>
.driver-view {
  width: 100%;
  height: 100%;
  overflow: hidden;

  .driver-container {
    height: 100%;
    width: 100%;
    overflow-x: hidden;
    overflow-y: auto;
  }
}

.driver {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  border: 1px solid #cecece;
  padding: 15px 10px;
  cursor: pointer;
  border-radius: 5px;

  &:hover {
    border-color: #4070ef;
    box-shadow: 0 0 20px 0 #4070ef;
  }

  &[isChecked='true'] {
    border-color: #4070ef;
    box-shadow: 0 0 20px 0 #4070ef;
    // filter: contrast(1.2);
  }

  &-logo {
    width: 100px;
    height: 75px;
    border: 1px dashed #f1f1f1;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    background: #f1f1f1;
    color: #333;
    border-radius: 25px;
    font-weight: 600;

    &[connect='true'][isbadcode='1'] {
      background: #f56c6c;
      color: #fff;
    }

    &[connect='true'][isbadcode='0'] {
      background: #67c23a;
      color: #fff;
    }
  }

  &-msg {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
  }

  &-content {
    width: 400px;
  }
}

:deep(.el-descriptions__header) {
  display: none;
}

.setoption {
  padding: 10px;
  border-radius: 15px;

  &-sesion {
    border: 2px dashed #748eef;
    padding: 10px;
    border-radius: 15px;
    margin-bottom: 10px;
  }
}
</style>
